/*
* created by kaweepapkongkittisan
*
*/


package com.tuinui.trade.controller.web;

import java.text.SimpleDateFormat;
import java.util.*;

import com.tuinui.trade.*;
import com.tuinui.trade.entry.PositionEntry;
import com.tuinui.trade.entry.PositionTodayEntry;
import com.tuinui.trade.entry.StockTradeDailyEntry;
import com.tuinui.trade.entry.TransactionEntry;
import com.tuinui.trade.manager.DataManager;
import com.tuinui.trade.service.StockTransactionService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.Validator;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

@Controller
public class BasicController {
    final public static Logger _log = LoggerFactory.getLogger(BasicController.class);

    @RequestMapping(value="/hello", method=RequestMethod.GET)
	public ModelAndView hello(){
		ModelAndView mv = new ModelAndView("hello");

		return mv;
	}
    @RequestMapping(value="/buy", method=RequestMethod.GET)
    public ModelAndView displayBuy(@ModelAttribute("position")PositionEntry position){
        ModelAndView mv = new ModelAndView("buy");
        Map<String, StockTradeDailyEntry> priceList = DataManager.getInstance().getCachedPrice();
        List<String> symbols = new ArrayList<String>(priceList.keySet());
        mv.addObject("symbols", symbols);
        mv.addObject("position", position);
        return mv;
    }
    @RequestMapping(value="/delete", method=RequestMethod.GET)
    public ModelAndView displayDelete(@ModelAttribute("position")PositionEntry position){
        ModelAndView mv = new ModelAndView("delete");
        mv.addObject("position", position);
        return mv;
    }
    @RequestMapping(value="/delete", method=RequestMethod.POST)
    public String delete(HttpServletRequest request,
                               HttpServletResponse response,
                               @ModelAttribute("position")PositionEntry position){
        StockTransactionService.getInstance().deletePosition(position);
        return "redirect:portfolio";
    }
    @RequestMapping(value="/update", method=RequestMethod.GET)
    public ModelAndView displayUpdate(@ModelAttribute("position")PositionEntry position){
        ModelAndView mv = new ModelAndView("update");
        mv.addObject("position", position);
        return mv;
    }
    @RequestMapping(value="/update", method=RequestMethod.POST)
    public String update(HttpServletRequest request,
                               HttpServletResponse response,
                               @ModelAttribute("position")PositionEntry position){
        StockTransactionService.getInstance().updatePosition(position);
        return "redirect:portfolio";
    }

    @RequestMapping(value="/sell", method=RequestMethod.GET)
    public ModelAndView displaySell(@ModelAttribute("position")PositionEntry position){
        ModelAndView mv = new ModelAndView("sell");
        Map<String, StockTradeDailyEntry> priceList = DataManager.getInstance().getCachedPrice();
        position.setPurchasedPrice(priceList.get(position.getSymbol()).getLast());
        mv.addObject("position", position);
        return mv;
    }
    @RequestMapping(value="/sell", method=RequestMethod.POST)
    public String sell(HttpServletRequest request,
                               HttpServletResponse response,
                               @ModelAttribute("position")PositionEntry position){
        StockTransactionService.getInstance().sellStock(position);
        return "redirect:portfolio";
    }

    @RequestMapping(value="/buy", method=RequestMethod.POST)
    public String buy(HttpServletRequest request,
                            HttpServletResponse response,
                            @Valid @ModelAttribute("position")PositionEntry position,
                            BindingResult result){

        if (result.hasErrors()){
            return "buy";
        }
        ModelAndView mv = new ModelAndView("portfolio");
        _log.debug("shares: " + position.getVolume());
        StockTransactionService.getInstance().buyStock(position);
        return "redirect:portfolio";
    }

    @RequestMapping(value="/portfolio", method=RequestMethod.GET)
    public ModelAndView portfolio(HttpServletRequest request,
                            HttpServletResponse response){
        ModelAndView mv = new ModelAndView("portfolio");
        Map<String, StockTradeDailyEntry> priceList = DataManager.getInstance().getCachedPrice();
        mv.addObject("priceList", priceList);

        List<PositionTodayEntry> positionList = DataManager.getInstance().getPositionList(request.getUserPrincipal().getName());
        mv.addObject("positionList", positionList);
        return mv;
    }
    @RequestMapping(value="/transactions", method=RequestMethod.GET)
    public ModelAndView transactionHistory(HttpServletRequest request,
                                  HttpServletResponse response){
        ModelAndView mv = new ModelAndView("transaction");
        List<TransactionEntry> transactionList = DataManager.getInstance().getTransactionList(request.getUserPrincipal().getName());
        mv.addObject("transactionList", transactionList);
        return mv;
    }




    @ModelAttribute("position")
    public PositionEntry populatePosition(HttpServletRequest request,
            HttpServletResponse response,
            @RequestParam(required=false, value="id") Long id)throws Exception{
        Object object = null;

        PositionEntry position = null;

        if (id != null){
            position = DataManager.getInstance().getPosition(id);


        }else{
            position = new PositionEntry();
            position.setOwner(request.getUserPrincipal().getName());
            position.setDate(new Date());

        }



        return position;


    }
    @RequestMapping(value="/download", method=RequestMethod.GET)
    public ModelAndView download(){
        ModelAndView mv = new ModelAndView("download");

        return mv;
    }

    @RequestMapping(value="/price-db", method=RequestMethod.GET)
    public ModelAndView savePriceToDB()throws Exception{
        ModelAndView mv = new ModelAndView("price");
        Map<String, StockTradeDailyEntry> entries = DataManager.getInstance().getCachedPrice();
        _log.debug("clean old stock price from database .....");

        DataManager.getInstance().cleanPrice();
        ArrayList a = new ArrayList<StockTradeDailyEntry>();
        a.addAll(entries.values());
        _log.debug("Saving stock price to database .....");

        DataManager.getInstance().savePriceList(a);
        _log.debug("Saved stock price to database .....");

        mv.addObject("priceList", a);
        return mv;

    }
    @RequestMapping(value="/price", method=RequestMethod.GET)
    public ModelAndView listPriceFromCache()throws Exception{
        ModelAndView mv = new ModelAndView("price");
        Map<String, StockTradeDailyEntry> entries = DataManager.getInstance().getCachedPrice();

        ArrayList a = new ArrayList<StockTradeDailyEntry>();
        a.addAll(entries.values());

        mv.addObject("priceList", a);
        return mv;

    }
	@RequestMapping(value="/price-live", method=RequestMethod.GET)
	public ModelAndView listPriceOnline()throws Exception{
		ModelAndView mv = new ModelAndView("price");
		String setUrl = "http://marketdata.set.or.th/mkt/aomstocklistresult.do?tradingMethod=aomstocklistresult.do&market=SET&language=th&country=TH";
		String maiUrl = "http://marketdata.set.or.th/mkt/aomstocklistresult.do?tradingMethod=aomstocklistresult.do&market=mai&language=th&country=TH";

		IStockPriceDownloader downloader = new StockPriceDownloaderAppengineImpl();
		downloader.setSource(new String[]{setUrl, maiUrl});
		List<StockTradeDailyEntry> entries = new ArrayList<StockTradeDailyEntry>();
		downloader.downloadSource();
		entries = downloader.extractStockPrice();

        _log.debug("Saving stock price to cache .....");
        DataManager.getInstance().setPriceCache(entries);
        _log.debug("Saved stock price to cache .....");
		mv.addObject("priceList", entries);

        _log.debug("number of stocks: " + entries.size());
		
		return mv;
	}

    @InitBinder
    protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception {
        SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
        CustomDateEditor editor = new CustomDateEditor(dateFormat, true);

        binder.registerCustomEditor(Date.class, editor);
    }
	
}
